package com.boot.interceptor;

import cn.hutool.core.util.StrUtil;
import com.boot.config.TokenStore;
import com.boot.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * JWT 认证拦截器
 * 拦截需要身份验证的请求，校验 Token 并设置用户上下文
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(AuthInterceptor.class);

    private final JwtUtil jwtUtil;
    private final TokenStore tokenStore;

    public AuthInterceptor(JwtUtil jwtUtil, TokenStore tokenStore) {
        this.jwtUtil = jwtUtil;
        this.tokenStore = tokenStore;
    }

    private static final String HEADER_AUTHORIZATION = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String authHeader = request.getHeader(HEADER_AUTHORIZATION);

        if (StrUtil.isBlank(authHeader) || !authHeader.startsWith(TOKEN_PREFIX)) {
            return unauthorized(response, "缺少认证令牌");
        }

        String token = authHeader.substring(TOKEN_PREFIX.length()).trim();

        // 1. 检查 token 是否在内存中有效（是否已被注销）
        if (!tokenStore.isValid(token)) {
            return unauthorized(response, "登录已失效，请重新登录");
        }

        try {
            // 2. 解析 JWT
            Claims claims = jwtUtil.parseToken(token);
            if (jwtUtil.isTokenExpired(claims)) {
                tokenStore.removeToken(token); // 自动清理过期 token
                return unauthorized(response, "令牌已过期");
            }

            return true; // 放行

        } catch (ExpiredJwtException e) {
            tokenStore.removeToken(token);
            return unauthorized(response, "令牌已过期");
        } catch (SignatureException | MalformedJwtException e) {
            return unauthorized(response, "无效的令牌格式");
        } catch (Exception e) {
            log.error("认证过程发生异常", e);
            return unauthorized(response, "认证失败：" + e.getMessage());
        }
    }

    private boolean unauthorized(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{\"code\":401,\"message\":\"" + message + "\",\"data\":null}");
        return false;
    }
}
